home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / Mailcheck Source / cdev src / mmc_cdev.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-18  |  16.4 KB  |  804 lines  |  [TEXT/KAHL]

  1. /*
  2.  * mail check control panel
  3.  * by Aaron Wohl (aw0g+@andrew.cmu.edu) jul 1990
  4.  * Carnegie-Mellon University
  5.  * Special Projects
  6.  * Pittsburgh, PA 15213-3890
  7.  * (412)-268-5032
  8.  */
  9.  
  10. #include <cdev.h>
  11. #include "mmc_core.h"
  12. #include "gms.h"
  13. #include "mmc_drvr_install.h"
  14. #include "mmc_drvr_find.h"
  15. #include "string.h"
  16. #include "mmc_prep.h"
  17. #include "mmc_os_preserve.h"
  18.  
  19. /*
  20.  * allocate some vars with newptr so they don't float around and
  21.  * can be passed to system calls
  22.  */
  23. struct fs_t_R {
  24.     TEHandle hTE;        /*text for user to check*/
  25.     Rect error_box;        /*box around error text*/
  26.     PicHandle arrows;    /*picture of an up and down arrow*/
  27.     Rect arrow_box;
  28.     Rect remind_box;
  29.     Rect sound_box;
  30.     long old_status;    /*driver status word*/
  31.     Str255 sound_text;
  32.  
  33.     int ref_num;
  34.     mmc_state cstate;
  35.     long last_state_update;
  36.     int init_done;
  37. };
  38. typedef struct fs_t_R fs_t,*fs_t_pt;
  39.  
  40. struct mailcheck : cdev {
  41.     fs_t *fs;            /*fixed allocated stuff*/
  42.     void compute_mmc(void);
  43.     void find_driver(void);
  44.     void set_display(void);
  45.     void set_check_box(int item,int setting);
  46.     void init_username_text(void);
  47.     void set_username_text(void);
  48.     void set_error_text(void);
  49.     void new_error(char *text);
  50.     int read_current_state_from_driver(mmc_state_pt s);
  51.     int really_read_current_state_from_driver(mmc_state_pt s);
  52.     int write_current_state_to_driver(mmc_state_pt s);
  53.     void applybutton(void);
  54.     void find_driver_state(void);
  55.     void usernametocur(void);
  56.     void init_arrows(void);
  57.     void set_remind_display(void);
  58.     void adjust_remind(long delta);
  59.     long figure_step(long direction);
  60.     void working_SetIText(Handle text,Str255 buf,Rect r);
  61.     void set_item_hilite(int item,int setting);
  62.     void set_status_text(char *new_text);
  63.     void set_new_status(long newst);
  64.     void check_new_status(long new_st);
  65.      void choose_sound(void);
  66.     void set_sound_display(void);
  67.     void set_sound(MenuHandle sound_pop,int pick);
  68.     void snooze(void);
  69.     int get_sound_menuid(MenuHandle sound_pop);
  70.  
  71.     void            Init(void);            /*  "initDev"  */
  72.     void            Close(void);        /*  "closeDev"  */
  73.     void            Activate(void);        /*  "activDev"  */
  74.     void            Update(void);        /*  "updateDev"  */
  75.     void            Idle(void);            /*  "nulDev"  */
  76.     void            ItemHit(short);        /*  "hitDev"  */
  77.     void            Key(short);            /*  "keyEvtDev"  */
  78.     void            CmdKey(short);        /*  "keyEvtDev" (command)  */
  79.     void            Deactivate(void);    /*  "deactiveDev"  */
  80.     void            Cut(void);            /*  "cutDev"  */
  81.     void            Copy(void);            /*  "copyDev"  */
  82.     void            Paste(void);        /*  "pasteDev"  */
  83.     void            Clear(void);        /*  "clearDev"  */
  84. };
  85.  
  86.  
  87. enum {
  88.     fn_user_name=1,
  89.     fn_enable_mail_checkbox=3,
  90.     fn_init_status_text=4,
  91.     fn_apply_button=5,
  92.     fn_last_user_checkbox=6,
  93.     fn_driver_status=7,
  94.     fn_remind_time=8,
  95.     fn_more_remind=9,
  96.     fn_less_remind=10,
  97.     fn_note=13,
  98.     fn_blink=14,
  99.     fn_snooze=15,
  100.     fn_sound=17,
  101.     fn_enable_sound=18
  102. };
  103.  
  104.  
  105. /*
  106.  *  Runnable - should the cdev appear in the Control Panel?
  107.  *
  108.  *  This implements the "macDev" message.
  109.  *
  110.  */
  111. Boolean Runnable()
  112. {
  113.     return true;
  114. }
  115.  
  116.  
  117. /*
  118.  *  New - create the cdev object
  119.  *
  120.  */
  121. cdev *New()
  122. {
  123.     return(new(mailcheck));
  124. }
  125.  
  126.  
  127. void mailcheck::find_driver()
  128. {
  129.     fs->ref_num=mmc_drvr_find(MMC_name,0L);
  130. }
  131.  
  132. /*
  133.  * set a checkbox as it is displayed
  134.  */
  135. void mailcheck::set_item_hilite(int item,int setting)
  136. {
  137.     short type;
  138.     Handle ctl;
  139.     Rect box;
  140.     GetDItem((WindowPtr)dp, lastItem + item, &type, &ctl, &box);
  141.     HiliteControl((ControlHandle)ctl,(setting)?1:0);
  142. }
  143.  
  144. /*
  145.  * set a checkbox as it is displayed
  146.  */
  147. void mailcheck::set_check_box(int item,int setting)
  148. {
  149.     short type;
  150.     Handle ctl;
  151.     Rect box;
  152.     Str255 buf;
  153.     GetDItem((WindowPtr)dp, lastItem + item, &type, &ctl, &box);
  154.     SetCtlValue((ControlHandle)ctl,(setting)?1:0);
  155. }
  156.  
  157. void mailcheck::set_username_text(void)
  158. {
  159.     int type;
  160.     Handle text;
  161.     Rect box;
  162.     Str255 buf;
  163.     int len=strlen(fs->cstate.mmc_uname);
  164.     len=imin(254,len);
  165.     if(len!=0)
  166.       memcpy(&buf[1],fs->cstate.mmc_uname,len);
  167.     buf[0]=len;
  168.     TESetText(&buf[1], buf[0],fs->hTE);
  169. }
  170.  
  171. /*
  172.  * initialize arrow drawing code
  173.  */
  174. void mailcheck::init_arrows()
  175. {
  176.     short type;
  177.     Handle user_item_handle;
  178.     Rect upbox;
  179.     int dx;
  180.     int dy;
  181.     GetDItem((WindowPtr)dp, lastItem + fn_more_remind, &type, &user_item_handle, &upbox);
  182.     fs->arrows=(PicHandle)GetNamedResource('PICT',"\pRemindArrows");
  183.     fs->arrow_box=(*(fs->arrows))->picFrame;
  184.     dx=fs->arrow_box.left-upbox.left;
  185.     dy=fs->arrow_box.top-upbox.top;
  186.     fs->arrow_box.left=upbox.left;
  187.     fs->arrow_box.top=upbox.top;
  188.     fs->arrow_box.right-=dx;
  189.     fs->arrow_box.bottom-=dy;
  190.  
  191.     fs->error_box=dp->port.portRect;
  192.     fs->remind_box=dp->port.portRect;
  193.     fs->sound_box=dp->port.portRect;
  194. }
  195.  
  196. /*
  197.  * set the username text
  198.  */
  199. void mailcheck::init_username_text()
  200. {
  201.     short type;
  202.     Handle text;
  203.     Rect box;
  204.     Str255 buf;
  205.     GetDItem((WindowPtr)dp, lastItem + fn_user_name, &type, &text, &box);
  206.     GetIText(text, buf);
  207.     SetDItem((WindowPtr)dp, lastItem + fn_user_name, userItem, 0, &box);
  208.     InsetRect(&box, 2, 2);
  209.     fs->hTE = TENew(&box, &box);
  210.     TEAutoView(true, fs->hTE);
  211.  
  212.     TESetText(&buf[1], buf[0], fs->hTE);
  213.     TESetSelect(0, 32767, fs->hTE);
  214.     TEActivate(fs->hTE);
  215. }
  216.  
  217. /*
  218.  * SetIText doesn't seem to invalidate....
  219.  */
  220. void mailcheck::working_SetIText(Handle text,Str255 buf,Rect r)
  221. {
  222.   GrafPtr old_port;
  223.   GetPort(&old_port);
  224.   SetPort(&dp->port);
  225.   SetIText(text,buf);
  226.   InvalRect(&r);
  227.   SetPort(old_port);
  228. }
  229.  
  230. void mailcheck::set_status_text(char *new_text)
  231. {
  232.     short type;
  233.     Handle text;
  234.     Rect box;
  235.     Str255 buf;
  236.     int len=strlen(new_text);
  237.     len=imin(254,len);
  238.     GetDItem((WindowPtr)dp, lastItem + fn_driver_status, &type, &text, &box);
  239.  
  240.     if(len!=0)
  241.       memcpy(&buf[1],new_text,len);
  242.     buf[0]=len;
  243.     working_SetIText(text,buf,box);
  244. }
  245.  
  246. LDEF(char *name_bit(long bit))
  247. {
  248.     switch(bit) {
  249.     case MCS_snooze:
  250.         return "snooze";
  251.     case MCS_want_open:
  252.         return "please_open";
  253.     case MCS_hearmm:
  254.         return "trackmm";
  255.     case MCS_io_pending:
  256.         return "io";
  257.     case MCS_debug:
  258.         return "debug";
  259.     case MCS_nsound:
  260.         return "sound";
  261.     case MCS_nblink:
  262.         return "blink";
  263.     case MCS_npost:
  264.         return "post";
  265.     default:
  266.         return "?";
  267.     }
  268. }
  269.  
  270.  
  271. LDEF(print_flags(char *buf,long aflag))
  272. {
  273.   char *sep="";
  274.   long i;
  275.   for(i=1;i!=0;i<<=1)
  276.     if((i&aflag)!=0) {
  277.       strcat(buf,sep);
  278.       strcat(buf,name_bit(i));
  279.       sep=", ";
  280.   }
  281. }
  282.  
  283. void mailcheck::set_new_status(long newst)
  284. {
  285.     char buf[300];
  286.     fs->old_status=newst;
  287.     buf[0]=0;
  288.     if((newst== -1)||
  289.        (newst== -2))
  290.         strcat(buf,"Driver not installed, enable, apply and reboot to start it.");
  291.     else if(newst== 0)
  292.         strcat(buf,"Driver is off");
  293.     else
  294.         print_flags(buf,newst);
  295.     set_status_text(buf);
  296.     
  297. }
  298.  
  299. void mailcheck::check_new_status(long newst)
  300. {
  301.     if(newst== fs->old_status)
  302.         return;
  303.     set_new_status(newst);
  304. }
  305.  
  306. void mailcheck::set_error_text()
  307. {
  308.     short type;
  309.     Handle text;
  310.     Rect box;
  311.     Str255 buf;
  312.     int len=strlen(fs->cstate.mmc_text_state);
  313.     len=imin(254,len);
  314.     GetDItem((WindowPtr)dp, lastItem + fn_init_status_text, &type, &text, &box);
  315.  
  316.     if(len!=0)
  317.       memcpy(&buf[1],fs->cstate.mmc_text_state,len);
  318.     buf[0]=len;
  319.     working_SetIText(text,buf,box);
  320.     InsetRect(&box,-2,-2);
  321.     fs->error_box=box;
  322. }
  323.  
  324. void mailcheck::new_error(char *text)
  325. {
  326.    if(strcmp(text,fs->cstate.mmc_text_state)==0)
  327.       return;
  328.      strcpy(fs->cstate.mmc_text_state,text);
  329.     set_error_text();
  330. }
  331.  
  332. #define CUR_MINS ((fs->cstate.mmc_remind_time+MINS-1)/MINS)
  333.  
  334. /*
  335.  * set the text displayed in the remind info
  336.  */
  337. void mailcheck::set_remind_display()
  338. {
  339.     short type;
  340.     Handle text;
  341.     Rect box;
  342.     Str255 buf;
  343.     NumToString(CUR_MINS,buf);
  344.     GetDItem((WindowPtr)dp, lastItem + fn_remind_time, &type, &text, &box);
  345.     working_SetIText(text,buf,box);
  346.     InsetRect(&box,-2,-1);
  347.     fs->remind_box=box;
  348. }
  349.  
  350. /*
  351.  * set the text displayed in the remind info
  352.  */
  353. LDEF(long set_sound_display_get(int id,unsigned char *sound_text))
  354. {
  355.     Handle res_han;
  356.     short res_id;
  357.     ResType res_type;
  358.     sound_res_state cur_res;
  359.     cur_res=mmc_use_sound_res();
  360.     res_han=GetResource('snd ',id);
  361.      if(res_han==0)
  362.         memcpy(sound_text,"\pSound?",10);
  363.     else
  364.       GetResInfo(res_han,&res_id,&res_type,sound_text);
  365.       mmc_close_sound_res(cur_res);
  366. }
  367.  
  368. void mailcheck::set_sound_display()
  369. {
  370.     short type;
  371.     Handle text;
  372.     Rect box;
  373.     Rect inv_rect;
  374.      
  375.     GetDItem((WindowPtr)dp, lastItem + fn_sound, &type, &text, &box);
  376.     fs->sound_box=box;
  377.  
  378.     OSP_protected_call(OSP_noload,set_sound_display_get,fs->cstate.mmc_sound_id,fs->sound_text);
  379.     inv_rect=fs->sound_box;
  380.     InsetRect(&inv_rect,1,1);
  381.     InvalRect(&inv_rect);
  382. }
  383.  
  384. /*
  385.  * see how big a step one click should do
  386.  */
  387. long mailcheck::figure_step(long direction)
  388. {
  389.     long result=5;            /*defult is 5min step*/
  390.     if(direction<0) {
  391.         if(CUR_MINS<=15)
  392.             result=1;
  393.     } else if(CUR_MINS<15)
  394.             result=1;
  395.     return result*direction;
  396. }
  397.  
  398. /*
  399.  * increase or decrease remind time
  400.  */
  401. void mailcheck::adjust_remind(long delta)
  402. {
  403.     long new_time=fs->cstate.mmc_remind_time+delta*MINS;
  404.     new_time=imax(0,new_time);
  405.     new_time=imin(new_time,999L*MINS);
  406.     if(new_time==fs->cstate.mmc_remind_time)
  407.       return;
  408.     fs->cstate.mmc_remind_time=new_time;
  409.     set_remind_display();
  410. }
  411.  
  412. /*
  413.  * set the user interface to match fs.cstate
  414.  */
  415. void mailcheck::set_display()
  416. {
  417.     set_check_box(fn_enable_mail_checkbox,FLSET(fs->cstate,MCS_want_open));
  418.     set_check_box(fn_last_user_checkbox,FLSET(fs->cstate,MCS_hearmm));
  419.     set_check_box(fn_note,FLSET(fs->cstate,MCS_npost));
  420.     set_check_box(fn_blink,FLSET(fs->cstate,MCS_nblink));
  421.     set_check_box(fn_enable_sound,FLSET(fs->cstate,MCS_nsound));
  422.     set_username_text();
  423.     set_remind_display();
  424.     set_error_text();
  425.     set_sound_display();
  426. }
  427.  
  428. int mailcheck::really_read_current_state_from_driver(mmc_state_pt s)
  429. {
  430.   int err;
  431.   if(fs->ref_num==0)
  432.       return FALSE;
  433.   err=mmc_get_drvr_state(fs->ref_num,s);
  434.   if(err!=0) {
  435.      strcpy(s->mmc_text_state,"Can't read_driver state");
  436.       return FALSE;
  437.   }
  438.   return TRUE;
  439. }
  440.  
  441. int mailcheck::read_current_state_from_driver(mmc_state_pt s)
  442. {
  443.     int err=really_read_current_state_from_driver(s);
  444.     if(!err)
  445.         check_new_status(-1);
  446.     else
  447.         check_new_status(s->mmc_st);
  448.     return err;
  449. }
  450.  
  451. void mailcheck::find_driver_state()
  452. {
  453.   mmc_state s;
  454.   if(read_current_state_from_driver(&s))
  455.     new_error(s.mmc_text_state);
  456. }
  457.  
  458.  
  459. int mailcheck::write_current_state_to_driver(mmc_state_pt s)
  460. {
  461.   int err;
  462.   err=mmc_set_drvr_state_sound_yes(fs->ref_num,s,MMC_set_state);
  463.   set_error_text();
  464.   return err;
  465. }
  466.  
  467. void mailcheck::usernametocur()
  468. {
  469.     char **text=(*fs->hTE)->hText;
  470.     int len;
  471.     len=imin(MMC_uname_len-1,GetHandleSize(text));
  472.     fs->cstate.mmc_uname[0]=0;
  473.     if(len!=0) {
  474.         memcpy(fs->cstate.mmc_uname,*text,len);
  475.         fs->cstate.mmc_uname[len]=0;
  476.     }
  477. }
  478.  
  479. void mailcheck::CmdKey(c)
  480. short c;
  481. {
  482.     switch(c) {
  483.       case 'd': case 'D':
  484.         fs->cstate.mmc_st^=MCS_debug;
  485.         break;
  486.       default:
  487.           inherited::CmdKey(c);
  488.     }
  489. }
  490.  
  491. void tick(int refnum);
  492. void tick(int refnum)
  493. {
  494.   mmc_io_record s;
  495.   INIT_CPB(s,refnum,MMC_run);
  496.   PBControlAsync((ParmBlkPtr)&s);
  497. }
  498.  
  499. void mailcheck::snooze()
  500. {
  501.     mmc_state s;
  502.     set_item_hilite(fn_snooze,TRUE);
  503.     memset(&s,0,sizeof(s));
  504.     s.mmc_st_maj_ver=MMC_ST_maj_ver;
  505.     s.mmc_st_min_ver=MMC_ST_min_ver;
  506.     if(fs->ref_num==0)
  507.         new_error("The MailCheck driver isn't running so how can it sleep?");
  508.     else
  509.         write_current_state_to_driver(&s);
  510.     set_item_hilite(fn_snooze,FALSE);
  511. }
  512.  
  513.  
  514. void mailcheck::applybutton()
  515. {
  516.     int prep_err;
  517.     int dr_err=0;
  518.     int new_ref;
  519.     set_item_hilite(fn_apply_button,TRUE);
  520.     usernametocur();
  521.     strcpy(fs->cstate.mmc_text_state,"Saved prefrences");
  522.  
  523. #ifdef RUBBISH
  524.     if((ref_num==0)&&(FLSET(*current_state,MCS_want_open)))
  525.         if((dr_err=mmc_drvr_find_or_install(&new_ref))==0)
  526.           if(OpenDriver(MMC_name,&new_ref)==0)
  527.           ref_num=new_ref;
  528. #endif
  529.  
  530.     dr_err=0;
  531.     if(fs->ref_num!=0) {
  532.       dr_err=write_current_state_to_driver(&fs->cstate);
  533.       tick(fs->ref_num);
  534.       tick(fs->ref_num);
  535.       tick(fs->ref_num);
  536.       set_display();
  537.      }
  538.     if(dr_err!=0)
  539.       new_error("Can't update driver state");
  540.     else {
  541.       prep_err=mmc_write_prep(&fs->cstate);
  542.       if(prep_err!=0)
  543.         new_error("Can't update MailCheck Pref file");
  544.    }
  545.    set_item_hilite(fn_apply_button,FALSE);
  546. }
  547.  
  548. void mailcheck::compute_mmc()
  549. {
  550.         if((!read_current_state_from_driver(&fs->cstate)) || (mmc_dont_like_prep(&fs->cstate)))
  551.           if((mmc_read_prep(&fs->cstate)!=0) || (mmc_dont_like_prep(&fs->cstate)))
  552.             mmc_invent_state(&fs->cstate);
  553.     set_display();
  554. }
  555.  
  556. /*
  557.  *  mailcheck::Init
  558.  *
  559.  *  A TE record is created to allow entry of mailcheck text.  For some
  560.  *  reason, editText dialog items don't seem to work in cdev's, so
  561.  *  we have to use a userItem.  (The item is listed as a statText item
  562.  *  in the DITL, giving us a convenient place to store the initial
  563.  *  text.  We change it to a userItem here.)
  564.  *
  565.  */
  566. void mailcheck::Init()
  567. {
  568.     
  569.     inherited::Init();
  570.     fs=(fs_t_pt)NewPtr(sizeof(*fs));
  571.     memset(fs,0,sizeof(*fs));
  572.     fs->init_done=FALSE;
  573.     fs->last_state_update=0;
  574.     fs->old_status= -2;
  575.     init_username_text();
  576.     init_arrows();
  577.  
  578.     find_driver();
  579.     compute_mmc();
  580.     fs->init_done=TRUE;
  581. }
  582.  
  583.  
  584. /*
  585.  *  mailcheck::Close
  586.  *
  587.  */
  588.  
  589. void mailcheck::Close()
  590. {
  591.     TEDispose(fs->hTE);
  592.     DisposPtr((Ptr)fs);
  593.     inherited::Close();
  594. }
  595.  
  596.  
  597. /*
  598.  *  mailcheck::Update
  599.  *
  600.  */
  601. void mailcheck::Update()
  602. {
  603.     Rect box = (**fs->hTE).viewRect;
  604.  
  605.     TEUpdate(&box, fs->hTE);
  606.     InsetRect(&box, -2, -2);
  607.     FrameRect(&box);
  608.  
  609.     if(fs->arrows!=0) {
  610.         Rect draw_where;
  611.         HLock((Handle)fs->arrows);
  612.         draw_where=fs->arrow_box;
  613.         DrawPicture(fs->arrows,&draw_where);
  614.         HUnlock((Handle)fs->arrows);
  615.     }
  616.     
  617.     FrameRect(&fs->error_box);
  618.     FrameRect(&fs->remind_box);
  619.     PenNormal();
  620.     EraseRect(&fs->sound_box);
  621.     FrameRect(&fs->sound_box);
  622.     MoveTo(fs->sound_box.left+1,fs->sound_box.bottom);
  623.     LineTo(fs->sound_box.right,fs->sound_box.bottom);
  624.     LineTo(fs->sound_box.right,fs->sound_box.top+1);
  625.     TextFont(0);
  626.     TextSize(12);
  627.     MoveTo(fs->sound_box.left+14,fs->sound_box.top+12);
  628.     DrawString(fs->sound_text);
  629. #define REMIND_OFFSET (5)
  630.     PenSize(1,2);
  631.     MoveTo(89,fs->error_box.top-REMIND_OFFSET);
  632.     LineTo(319,fs->error_box.top-REMIND_OFFSET);
  633.     PenNormal();
  634. }
  635.  
  636.  
  637. void mailcheck::Activate()
  638. {
  639.     TEActivate(fs->hTE);
  640. }
  641.  
  642.  
  643. void mailcheck::Deactivate()
  644. {
  645.     TEDeactivate(fs->hTE);
  646. }
  647.  
  648. LDEF(long inner_get_named(unsigned char *name))
  649. {
  650.     return (long)GetNamedResource('snd ',name);
  651. }
  652.  
  653. void mailcheck::set_sound(MenuHandle sound_pop,int pick)
  654. {
  655.     Str255 buf;
  656.     short res_id;
  657.     ResType res_type;
  658.     Handle res_han;
  659.     int prev_res;
  660.     GetItem(sound_pop,pick,buf);
  661.     res_han=(Handle)OSP_protected_call(OSP_noload,inner_get_named,buf);
  662.     if(res_han==0)
  663.         return;
  664.     GetResInfo(res_han,&res_id,&res_type,buf);
  665.     ReleaseResource(res_han);
  666.     fs->cstate.mmc_sound_id=res_id;
  667. }
  668.  
  669. int mailcheck::get_sound_menuid(MenuHandle sound_pop)
  670. {
  671.     int i;
  672.     Str255 buf;
  673.     for(i=CountMItems(sound_pop);i>0;i--) {
  674.         GetItem(sound_pop,i,buf);
  675.         if(memcmp(buf,fs->sound_text,buf[0])==0)
  676.             return i;
  677.     }
  678.     return 0;
  679. }
  680.  
  681. void mailcheck::choose_sound()
  682. {
  683. #define POP_UP_ID (2312)
  684.     MenuHandle sound_pop;
  685.     int menu_pick;
  686.     Point pop_loc;
  687.     int old_res_file;
  688.     int new_res_file;
  689.     sound_res_state prev_res;
  690.     int def_item;
  691.     pop_loc.v=fs->sound_box.top;
  692.     pop_loc.h=fs->sound_box.left;
  693.     LocalToGlobal(&pop_loc);
  694.     sound_pop=NewMenu(POP_UP_ID,"\pSound Popup");
  695.     if(sound_pop==0) return;
  696.     prev_res=mmc_use_sound_res();
  697.     AddResMenu(sound_pop,'snd ');
  698.     InsertMenu(sound_pop,-1);
  699.     def_item=get_sound_menuid(sound_pop);
  700.     CheckItem(sound_pop,def_item,TRUE);
  701.     menu_pick=PopUpMenuSelect(sound_pop,
  702.         pop_loc.v,pop_loc.h,def_item);
  703.     set_sound(sound_pop,menu_pick);
  704.     DeleteMenu(POP_UP_ID);
  705.     DisposeMenu(sound_pop);
  706.     mmc_close_sound_res(prev_res);
  707.  
  708.     set_sound_display();
  709. }
  710.  
  711. void mailcheck::ItemHit(item)
  712. short item;
  713. {
  714.     Point where;
  715.  
  716.     switch(item) {
  717.     case fn_user_name:
  718.         where = event->where;
  719.         GlobalToLocal(&where);
  720.         TEClick(where, (event->modifiers & shiftKey) ? true : false, fs->hTE);
  721.         break;
  722.     case fn_last_user_checkbox:
  723.         fs->cstate.mmc_st^=MCS_hearmm;
  724.         set_check_box(fn_last_user_checkbox,FLSET(fs->cstate,MCS_hearmm));
  725.         break;
  726.     case fn_enable_mail_checkbox:
  727.         fs->cstate.mmc_st^=MCS_want_open;
  728.         set_check_box(fn_enable_mail_checkbox,FLSET(fs->cstate,MCS_want_open));
  729.         break;
  730.     case fn_note:
  731.         fs->cstate.mmc_st^=MCS_npost;
  732.         set_check_box(fn_note,FLSET(fs->cstate,MCS_npost));
  733.         break;
  734.     case fn_blink:
  735.         fs->cstate.mmc_st^=MCS_nblink;
  736.         set_check_box(fn_blink,FLSET(fs->cstate,MCS_nblink));
  737.         break;
  738.     case fn_enable_sound:
  739.         fs->cstate.mmc_st^=MCS_nsound;
  740.         set_check_box(fn_enable_sound,FLSET(fs->cstate,MCS_nsound));
  741.         break;
  742.     case fn_sound:
  743.         choose_sound();
  744.         break;
  745.     case fn_apply_button:
  746.         applybutton();
  747.         break;
  748.     case fn_more_remind:
  749.         adjust_remind(figure_step(+1L));
  750.         break;
  751.     case fn_less_remind:
  752.         adjust_remind(figure_step(-1));
  753.         break;
  754.     case fn_snooze:
  755.         snooze();
  756.         break;
  757.     case fn_init_status_text:
  758.         break;
  759.     default:
  760.         break;
  761.     }
  762. }
  763.  
  764. void mailcheck::Idle()
  765. {
  766.     if(!fs->init_done)
  767.         return;
  768.     find_driver_state();
  769.     TEIdle(fs->hTE);
  770. }
  771.  
  772.  
  773. void mailcheck::Key(c)
  774. short c;
  775. {
  776.     TEKey(c, fs->hTE);
  777. }
  778.  
  779. void mailcheck::Cut()
  780. {
  781.     if ((**fs->hTE).selStart != (**fs->hTE).selEnd)
  782.         TECut(fs->hTE);
  783. }
  784.  
  785.  
  786. void mailcheck::Copy()
  787. {
  788.     if ((**fs->hTE).selStart != (**fs->hTE).selEnd)
  789.         TECopy(fs->hTE);
  790. }
  791.  
  792.  
  793. void mailcheck::Paste()
  794. {
  795.     if (TEScrpLength)
  796.         TEPaste(fs->hTE);
  797. }
  798.  
  799.  
  800. void mailcheck::Clear()
  801. {
  802.     TEDelete(fs->hTE);
  803. }
  804.